//
// CrackZipFile
//
// Copyright (C) jextra.net.
//
//  This file is part of the Crack build system.
//
//  The Crack build system is free software; you can redistribute it 
//  and/or modify it under the terms of the GNU Lesser General Public
//  License as published by the Free Software Foundation; either
//  version 2.1 of the License, or (at your option) any later version.
//
//  The Crack build system is distributed in the hope that it will be 
//  useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
//  Lesser General Public License for more details.
//
//  You should have received a copy of the GNU Lesser General Public
//  License along with the Crack build system; if not, write to the Free
//  Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
//  02111-1307 USA.
//

package net.jextra.crack.tool;

import java.io.*;
import java.util.zip.*;
import net.jextra.crack.type.*;

/**
 * <p>
 * ZIP file manipulation.
 * </p>
 */
public class CrackZipFile
{
    // ============================================================
    // Fields
    // ============================================================

    private File file;
    private ZipOutputStream out;

    // ============================================================
    // Constructors
    // ============================================================

    public CrackZipFile( String filename )
        throws FileNotFoundException
    {
        this( new File( filename ) );
    }

    public CrackZipFile( File file )
        throws FileNotFoundException
    {
        this.file = file;
    }

    public CrackZipFile( OutputStream outStream )
    {
        out = new ZipOutputStream( outStream );
    }

    // ============================================================
    // Methods
    // ============================================================

    // ----------
    // public
    // ----------

    public void addFiles( StrainedFileSet fileSet )
        throws IOException
    {
        byte[] buf = new byte[5000];

        for ( File file : fileSet.getFiles() )
        {
            int rootLen = fileSet.getRootDir().getCanonicalPath().length();

            FileInputStream in = new FileInputStream( file );
            String name = file.getCanonicalPath().substring( rootLen + 1 ).replace( '\\', '/' );
            System.out.println( name );
            getOut().putNextEntry( new ZipEntry( name ) );

            int len;
            while ( ( len = in.read( buf ) ) > 0 )
            {
                getOut().write( buf, 0, len );
            }

            in.close();
            getOut().closeEntry();
        }
    }

    public void close()
        throws IOException
    {
        if ( getOut() != null )
        {
            getOut().close();
        }
    }

    public void explode( File dir )
        throws IOException
    {
        ZipInputStream in = new ZipInputStream( new FileInputStream( file ) );
        byte[] buf = new byte[5000];

        for ( ZipEntry entry = in.getNextEntry(); entry != null; entry = in.getNextEntry() )
        {
            File outFile = new File( dir, entry.getName() );
            outFile.getParentFile().mkdirs();
            FileOutputStream out = new FileOutputStream( outFile );
            
            int len;
            while ( ( len = in.read( buf ) ) > 0 )
            {
                out.write( buf, 0, len );
            }
            
            out.close();
        }
        
        in.close();
    }

    // ----------
    // private
    // ----------

    private ZipOutputStream getOut()
        throws FileNotFoundException
    {
        if ( out == null )
        {
            out = new ZipOutputStream( new FileOutputStream( file ) );
        }

        return out;
    }
}

